package com.hskn.hss.filter;

import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

//@RestControllerAdvice
@Slf4j
public class ResponseFilter implements Filter {
    private FilterConfig config = null;

    private final String[] NULL_STRING_ARRAY = new String[0];
    private final String URL_SPLIT_PATTERN = "[, ;\r\n]";//逗号  空格 分号  换行

    private final PathMatcher pathMatcher = new AntPathMatcher();

    private final Logger logger = LoggerFactory.getLogger("url.filter");

    /**
     * 白名单
     */
    private String[] whiteListURLs = {};

    /**
     * 黑名单
     */
    private String[] blackListURLs = {"/hss/tlresplan/getList"};

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
            throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String currentURL = httpRequest.getServletPath();

        if (isBlackURL(currentURL)) {
            PrintWriter out = response.getWriter();
            String str;
            ResponseWrapper wrapperResponse = new ResponseWrapper((HttpServletResponse) response);//转换成代理类
            // 这里只拦截返回，直接让请求过去，如果在请求前有处理，可以在这里处理
            filterChain.doFilter(request, wrapperResponse);
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json; charset=utf-8");
            byte[] content = wrapperResponse.getContent();//获取返回值
            //判断是否有值
            str = new String(content, "UTF-8");
            if (content.length > 0) {
                System.out.println("返回值:" + str);
                String ciphertext = null;
                try {
                    ciphertext = str.replace("null", "\'\'");
                } catch (Exception e) {
                    e.printStackTrace();
                }
                //把返回值输出到客户端
                JSONObject res = new JSONObject();
                res = JSONObject.fromObject(ciphertext);
                out.append(res.toString());
                //我测试了需要加上这行代码,才能对 response的内容 修改生效，
                //好像是需要保持长度一致，不然请求就一直会处于等待，希望对后来的小伙伴有点帮助
                //out.setContentLength(ciphertext.getBytes().length);
                /// out.write(ciphertext.getBytes());
                out.flush();
            }
        } else {
            filterChain.doFilter(request, response);
        }
    }

    private boolean isWhiteURL(String currentURL) {
        for (String whiteURL : whiteListURLs) {
            if (pathMatcher.match(whiteURL, currentURL)) {
                logger.debug("url filter : white url list matches : [{}] match [{}] continue", whiteURL, currentURL);
                return true;
            }
            logger.debug("url filter : white url list not matches : [{}] match [{}]", whiteURL, currentURL);
        }
        return false;
    }

    private boolean isBlackURL(String currentURL) {
        for (String blackURL : blackListURLs) {
            if (pathMatcher.match(blackURL, currentURL)) {
                logger.debug("url filter : black url list matches : [{}] match [{}] break", blackURL, currentURL);
                return true;
            }
            logger.debug("url filter : black url list not matches : [{}] match [{}]", blackURL, currentURL);
        }
        return false;
    }

    @Override
    public void init(FilterConfig arg0)
            throws ServletException {

    }

    @Override
    public void destroy() {

    }

    private void initConfig() {
        String whiteListURLStr = this.config.getInitParameter("whiteListURL");
        whiteListURLs = strToArray(whiteListURLStr);

        String blackListURLStr = this.config.getInitParameter("blackListURL");
        blackListURLs = strToArray(blackListURLStr);

    }

    private String[] strToArray(String urlStr) {
        if (urlStr == null) {
            return NULL_STRING_ARRAY;
        }
        String[] urlArray = urlStr.split(URL_SPLIT_PATTERN);

        List<String> urlList = new ArrayList<String>();

        for (String url : urlArray) {
            url = url.trim();
            if (url.length() == 0) {
                continue;
            }

            urlList.add(url);
        }

        return urlList.toArray(NULL_STRING_ARRAY);
    }

    public FilterConfig getConfig() {
        return config;
    }

}
